﻿using CommonAdmin.Dto;
using CommonAdmin.Model;
using CommonAdmin.Util;
using CommonAdmin.Web.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System.Text.Json.Nodes;
using System.Text.Json;
using CommonAdmin.Web.Converter;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authorization.Infrastructure;
namespace CommonAdmin.Web.Controllers.Api
{
	[ApiController]
	[Route("api/[controller]")]
	public class UserController : ApiBaseController
	{
		public UserController(ILogger<UserController> logger, ISqlSugarClient db) : base(logger, db) { }
		/// <summary>
		/// 获取验证码
		/// </summary>
		/// <returns></returns>
		[HttpGet("getcode")]
		public string GetCode()
		{
			var code = Tools.GetRandomizer(Constants.CodeLenth);//生成验证码
			HttpContext.Session.SetString(Constants.Session_Key_Code, code);//设置session
			return code;
		}
		/// <summary>
		/// 登录
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("login")]		
		public JsonResult Login([FromBody] JsonObject data)
		{
			string username = data["username"]!.GetValue<string>();
			string password = data["password"]!.GetValue<string>();
			string vercode = data["vercode"]!.GetValue<string>();
			ResultViewModel result = new ResultViewModel();
			UserDto user = null;
			try
			{
				result.code = (int)CodeEnum.请求失败;

				var login_code = HttpContext.Session.GetString(Constants.Session_Key_Code);//获取code
				if (string.IsNullOrWhiteSpace(vercode) || login_code == null || !login_code.Equals(vercode, StringComparison.CurrentCultureIgnoreCase))
				{
					result.msg = "验证码错误";
					return new JsonResult(result);
				}

				if (!string.IsNullOrWhiteSpace(username) && !string.IsNullOrWhiteSpace(password))
				{
					user = _db.Queryable<UserDto>().First(o => o.Account == username && o.Password == Tools.EncryptByMD5(password));
					if (user!=null)
					{
						if (user.Status != EnumStatus.Available)
						{
							result.msg = "该用户已被禁用，请联系管理员";
						}
						else
						{
							result.code = (int)CodeEnum.请求成功;
							result.data = "/Main/Index";//登录后页面
							//设置session
							//HttpContext.Session.SetString(Constants.Session_Key_UserName, user.Name);
							HttpContext.Session.SetString(Constants.Session_Key_UserId, user.Id);
						}
					}
					else
					{
						result.msg = "用户名或密码错误";
					}
				}
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "登陆失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("用户登陆", user, null);				
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 注销
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpGet("logout")]
		public JsonResult Logout()
		{				
			ResultViewModel result = new ResultViewModel();			
			try
			{				
				result.code = (int)CodeEnum.请求成功;
				HttpContext.Session.Remove(Constants.Session_Key_Code);				
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "注销失败");
			}			
			return new JsonResult(result);
		}

		/// <summary>
		/// 用户列表
		/// </summary>
		/// <param name="page"></param>
		/// <param name="limit"></param>
		/// <param name="keyword"></param>
		/// <param name="status"></param>
		/// <returns></returns>
		[HttpGet("list")]
		public JsonResult GetList(int page, int limit, string keyword, string status)
		{
			ResultViewModel result = new ResultViewModel();
			try
			{
				result.code = (int)CodeEnum.请求成功;
				int total = 0;
				var list = _db.Queryable<UserDto>()
					.WhereIF(!string.IsNullOrWhiteSpace(keyword), u => u.Name.Contains(keyword)||u.Account.Contains(keyword) ||u.Email.Contains(keyword)||u.Tel.Contains(keyword) ||u.Bak.Contains(keyword))
					.WhereIF(!string.IsNullOrEmpty(status), u => u.Status == (EnumStatus)Enum.Parse(typeof(EnumStatus), status))
					.OrderBy(u => u.CreateTime)
					.ToPageList(page, limit, ref total);
				result.rows = total;
				result.data = list;
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "获取用户列表失败");
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 添加用户
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("add")]
		public JsonResult Add([FromBody] JsonObject data)
		{
			string name = data["name"]!.GetValue<string>();
			string account = data["account"]!.GetValue<string>();
			string email = data["email"]!.GetValue<string>();
			string tel = data["tel"]!.GetValue<string>();
			string bak = data["bak"]!.GetValue<string>();
			int status = int.Parse(data["status"]!.GetValue<string>());
			ResultViewModel result = new ResultViewModel();
			if (string.IsNullOrWhiteSpace(name))
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户名称不能为空";
				return new JsonResult(result);
			}
			if (_db.Queryable<UserDto>().Where(u => u.Name == name).Count() > 0)
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户名称已存在";
				return new JsonResult(result);
			}
			var dto = new UserDto()
			{
				Id = Tools.NewGuid(),
				Name = name,
				Account = account,
				Password = Tools.EncryptByMD5(Constants.DefaultPassword),
				Email = email,
				Tel = tel,
				Bak = bak,
				Status = (EnumStatus)status,
				CreateTime = DateTime.Now,
				UpdateTime = DateTime.Now,
			};
			try
			{
				result.code = (int)CodeEnum.请求成功;
				_db.Insertable<UserDto>(dto).ExecuteCommand();
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "添加用户失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("添加用户",dto,null);
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 删除用户
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("del")]
		public JsonResult Delete([FromBody] JsonObject data)
		{
			string id = data["id"]!.GetValue<string>();
			ResultViewModel result = new ResultViewModel();
			if (string.IsNullOrWhiteSpace(id))
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户Id不能为空";
				return new JsonResult(result);
			}
			if (id == Constants.SystemId)
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "内置用户不能删除";
				return new JsonResult(result);
			}
			var user = _db.Queryable<UserDto>().First(u=>u.Id==id);
			try
			{
				result.code = (int)CodeEnum.请求成功;
				_db.Deleteable<UserDto>(user).ExecuteCommand();
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "删除用户失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("删除用户",user,null);
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 修改用户
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("edit")]
		public JsonResult Update([FromBody] JsonObject data)
		{
			string id = data["id"]!.GetValue<string>();
			string name = data["name"]!.GetValue<string>();
			string account = data["account"]!.GetValue<string>();
			string email = data["email"]!.GetValue<string>();
			string tel = data["tel"]!.GetValue<string>();
			string bak = data["bak"]!.GetValue<string>();
			int status = int.Parse(data["status"]!.GetValue<string>());
			ResultViewModel result = new ResultViewModel();
			if (string.IsNullOrWhiteSpace(id))
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户Id不能为空";
				return new JsonResult(result);
			}
			if (id == Constants.SystemId)
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "内置用户不能修改";
				return new JsonResult(result);
			}
			var oldUser = _db.Queryable<UserDto>().First(u=>u.Id==id);
			var newUser = new UserDto()
			{
				Id = id,
				Name = name,
				Account = account,
				Email = email,
				Tel = tel,
				Bak = bak,
				Status = (EnumStatus)status,
				UpdateTime = DateTime.Now,
			};
			try
			{
				result.code = (int)CodeEnum.请求成功;
				_db.Updateable<UserDto>(newUser).IgnoreColumns(u => new { u.Password,u.CreateTime})
				.ExecuteCommand();
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "修改用户失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("修改用户",oldUser,newUser);
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 重置用户密码
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("reset")]
		public JsonResult Reset([FromBody] JsonObject data)
		{
			string id = data["id"]!.GetValue<string>();			
			ResultViewModel result = new ResultViewModel();
			if (string.IsNullOrWhiteSpace(id))
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户Id不能为空";
				return new JsonResult(result);
			}
			var user = _db.Queryable<UserDto>().First(o=>o.Id==id);
			try
			{
				result.code = (int)CodeEnum.请求成功;
				_db.Updateable<UserDto>(new UserDto()
				{
					Id = id,
					Password= Tools.EncryptByMD5(Constants.DefaultPassword),
				}).IgnoreColumns(u => new { u.Name,u.Account,u.Email,u.Tel,u.Bak,u.Status,u.CreateTime,u.UpdateTime })
				.ExecuteCommand();
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "重置密码失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("重置密码",user,null);				
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 用户所属角色列表
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("rolelist")]
		public JsonResult RoleList([FromBody] JsonObject data)
		{
			string userId = data["userId"]!.GetValue<string>();
			ResultViewModel result = new ResultViewModel();
			if (string.IsNullOrWhiteSpace(userId))
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户Id不能为空";
				return new JsonResult(result);
			}
			
			try
			{
				result.code = (int)CodeEnum.请求成功;
				List<string> roles = new List<string>();
				foreach (var item in _db.Queryable<UserRoleDto>().Where(o => o.UserId == userId).ToList())
				{
					roles.Add(item.RoleId);
				}
				result.data = roles;				
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "获取用户角色失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("获取用户角色失败", null, null);
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 修改用户所属角色
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("editrole")]
		public JsonResult UpdateRole([FromBody] JsonObject data)
		{
			string userId = data["userId"]!.GetValue<string>();
			var roleIds = data["roleIds"]!.AsArray();
			ResultViewModel result = new ResultViewModel();
			if (string.IsNullOrWhiteSpace(userId))
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户Id不能为空";
				return new JsonResult(result);
			}

			try
			{
				result.code = (int)CodeEnum.请求成功;
				_db.Deleteable<UserRoleDto>().Where(o=>o.UserId==userId);//先全部删除
																		 
				List<UserRoleDto> list = new List<UserRoleDto>();
				foreach (var id in roleIds)
				{
					list.Add(new UserRoleDto() { UserId=userId,RoleId=id!.GetValue<string>()});
				}
				_db.Insertable(list).ExecuteCommand();//再批量添加			
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "修改用户角色失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("修改用户角色失败", null, null);
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 修改用户信息
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("editinfo")]
		public JsonResult UpdateInfo([FromBody] JsonObject data)
		{
			string id = data["id"]!.GetValue<string>();
			string name = data["name"]!.GetValue<string>();			
			string email = data["email"]!.GetValue<string>();
			string tel = data["tel"]!.GetValue<string>();
			string bak = data["bak"]!.GetValue<string>();			
			ResultViewModel result = new ResultViewModel();
			if (string.IsNullOrWhiteSpace(id))
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户Id不能为空";
				return new JsonResult(result);
			}
			
			var oldUser = _db.Queryable<UserDto>().First(u => u.Id == id);
			var newUser = new UserDto()
			{
				Id = id,
				Name = name,				
				Email = email,
				Tel = tel,
				Bak = bak,
				UpdateTime = DateTime.Now,
			};
			try
			{
				result.code = (int)CodeEnum.请求成功;
				_db.Updateable<UserDto>(newUser).IgnoreColumns(u => new { u.Password, u.CreateTime,u.Account,u.Status })
				.ExecuteCommand();
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "修改用户信息失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("修改用户信息", oldUser, newUser);
			}
			return new JsonResult(result);
		}
		/// <summary>
		/// 修改密码
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		[HttpPost("changepass")]
		public JsonResult ChangePassword([FromBody] JsonObject data)
		{
			string id = data["id"]!.GetValue<string>();
			string oldpassword = data["oldpassword"]!.GetValue<string>();
			string newpassword = data["newpassword"]!.GetValue<string>();
			string repassword = data["repassword"]!.GetValue<string>();
			ResultViewModel result = new ResultViewModel();
			if (string.IsNullOrWhiteSpace(id))
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "用户Id不能为空";
				return new JsonResult(result);
			}
			if (oldpassword == newpassword)
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "新旧密码不能相同";
				return new JsonResult(result);
			}
			if (newpassword != repassword)
			{
				result.code = (int)CodeEnum.请求失败;
				result.msg = "确认密码与新密码不一致";
				return new JsonResult(result);
			}
			var user = _db.Queryable<UserDto>().First(o => o.Id == id);
			try
			{
				result.code = (int)CodeEnum.请求成功;
				if (user == null)
				{
					result.code = (int)CodeEnum.请求失败;
					result.msg = "用户不存在";
					return new JsonResult(result);
				}
				if (user.Password != Tools.EncryptByMD5(oldpassword))
				{
					result.code = (int)CodeEnum.请求失败;
					result.msg = "密码错误";
					return new JsonResult(result);
				}
				
				_db.Updateable<UserDto>(new UserDto()
				{
					Id = id,
					Password = Tools.EncryptByMD5(newpassword),
				}).IgnoreColumns(u => new { u.Name, u.Account, u.Email, u.Tel, u.Bak, u.Status, u.CreateTime, u.UpdateTime })
				.ExecuteCommand();
			}
			catch (Exception ex)
			{
				result.code = (int)CodeEnum.内部错误;
				result.msg = CodeEnum.内部错误.ToString();
				_logger.LogError(ex, "修改密码失败");
			}
			if (result.code == (int)CodeEnum.请求成功)
			{//记录日志
				base.SaveDbLog<UserDto>("修改密码", null, null);
			}
			return new JsonResult(result);
		}
	}
}
